package library;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.HashMap;
import java.util.HashSet;

import library.IF.CustomerDAO;

/**
 * The Class Customer.
 * 
 * @author Pim Hazebroek
 */
public class Customer implements Serializable {
	private static final long serialVersionUID = 1L;

	private static String filename = System.getProperty("user.dir") + "/customers.dat";

	private static HashMap<String, Customer> customers = load();

	/**
	 * Find customer.
	 * 
	 * @param name the name
	 * 
	 * @return the customer
	 */
	static Customer findCustomer(String name) {
		synchronized (customers) {
			return customers.get(name);
		}
	}

	/**
	 * Removes the customer.
	 * 
	 * @param name the name
	 */
	static void removeCustomer(String name) {
		synchronized (customers) {
			customers.remove(name);
		}
	}

	/**
	 * All customers.
	 * 
	 * @return the hash set<CustomerDAO>
	 */
	static HashSet<CustomerDAO> allCustomers() {
		HashSet<CustomerDAO> customersDAO = new HashSet<CustomerDAO>();
		synchronized (customers) {
			for (Customer c : customers.values()) {
				CustomerDAO customer = new CustomerDAO();
				customer.setName(c.getName());

				HashSet<Book> books = c.getNormalBooks();
				for (Book b : books) {
					customer.addBook(b.getTitle());
					
				}				
				customersDAO.add(customer);
			}
		}
		return customersDAO;
	}

	/** ***********************\ Object \*********************************. */
	/** The name. */
	private String name = null;

	/** The credits. */
	private int credits = 0;

	/** The books. */
	private HashSet<Book> books = new HashSet<Book>();

	/**
	 * Instantiates a new customer.
	 * 
	 * @param newName
	 *            the new name
	 */
	Customer(String newName) {
		name = newName;
		synchronized (customers) {
			customers.put(name, this);
			save();
		}
	}

	/**
	 * Gets the name.
	 * 
	 * @return the name
	 */
	public String getName() {
		return name;
	}

	/**
	 * Gets the credits.
	 * 
	 * @return the credits
	 */
	public int getCredits() {
		return credits;
	}

	/**
	 * Sets the credits.
	 * 
	 * @param newCredits
	 *            the new credits
	 */
	public void setCredits(int newCredits) {
		credits = newCredits;
	}

	/**
	 * Gets the books.
	 * 
	 * @return the books
	 */
	HashSet<Book> getNormalBooks() {
		return books;
	}

	/**
	 * Gets the bookDAO's.
	 * 
	 * @return the bookDAO's
	 */
	public HashSet<String> getBooks() {

		HashSet<String> titles = new HashSet<String>();
		for (Book b : books) {
			titles.add(b.getTitle());
		}

		return titles;
	}

	/**
	 * Adds the book.
	 * 
	 * @param book
	 *            the book
	 */
	public void addBook(Book book) {
		books.add(book);
	}

	/**
	 * Removes the book.
	 * 
	 * @param book
	 *            the book
	 */
	public void removeBook(Book book) {
		books.remove(book);
	}

	private void save() {
		System.out.println("Customer.save()");
		try {
			System.out.println("Saving customers...");
			ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(filename));
			oos.writeObject(customers);
			oos.close();
			System.out.println("Done saving!");
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	@SuppressWarnings("unchecked")
	private static HashMap<String, Customer> load() {
		HashMap<String, Customer> customers = new HashMap<String, Customer>();
		try {
			ObjectInputStream ois = new ObjectInputStream(new FileInputStream(filename));
			customers = (HashMap<String, Customer>) ois.readObject();
			return customers;
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		return customers;
	}

	@Override
	public String toString() {
		String ret = "[Customer: " + name;
		for (Book book : books) {
			ret += (" " + book.getTitle());
		}
		return "customer";
	}
}
